home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Camelot / Camelot 059 (1989-12)(Swedish User Group of Amiga)(SE)(PD)[WB].zip / Camelot 059 (1989-12)(Swedish User Group of Amiga)(SE)(PD)[WB].adf / Utils / du.c < prev    next >
C/C++ Source or Header  |  1989-11-14  |  5KB  |  227 lines

  1. #include <exec/types.h>
  2. #include <string.h>
  3. #include <proto/exec.h>
  4. #include <proto/dos.h>
  5. #include <libraries/dos.h>
  6.  
  7. BPTR stdin, stdout;
  8. int subdisp = TRUE, verbose = FALSE;
  9.  
  10. char *error_message[] = {
  11.    "No default directory", /* 201 */
  12.    "Object in use",
  13.    "Object exists",
  14.    "Directory not found",
  15.    "Object not found",
  16.    "Bad stream name",
  17.    "Object too large",
  18.    "Unknown error 208",
  19.    "Action not known",
  20.    "Invalid component name",
  21.    "Invalid lock",
  22.    "Object is of wrong type",
  23.    "Disk not validated",
  24.    "Disk write protected",
  25.    "Rename across devices",
  26.    "Directory not empty",
  27.    "Too many levels",
  28.    "Device not mounted",
  29.    "Seek error",
  30.    "Comment too big",
  31.    "Disk full",
  32.    "Delete protected",
  33.    "Write protected",
  34.    "Read protected",
  35.    "Not a DOS disk",
  36.    "No disk"
  37. };
  38.  
  39. void MemCleanup() { }
  40.  
  41. void disp_error(int err, char *s)
  42. {
  43.    printf("%ls -- ", s);
  44.  
  45.    if (err >= 201 && err <= 226)
  46.       printf(error_message[err - 201]);
  47.    else
  48.       switch (err) {
  49.          case 0:
  50.             printf("No error!!!");
  51.             break;
  52.          case ERROR_NO_FREE_STORE:
  53.             printf("No free store");
  54.             break;
  55.          case ERROR_NO_MORE_ENTRIES:
  56.             printf("No more entries");
  57.             break;
  58.          default:
  59.             printf("Unknown error %ld", err);
  60.             break;
  61.       }
  62.    putchar('\n');
  63. }
  64.  
  65. char *pathcat(to,from)
  66. register char to[], from[];
  67. {
  68.    register int l;
  69.  
  70.    l = strlen(to) - 1;
  71.    if (l < 0 || to[l] == ':' || to[l] == '/')
  72.       strcat(to,from);
  73.    else
  74.       strcat(strcat(to, "/"), from);
  75.  
  76.    return (to);
  77. }
  78.  
  79. struct FileInfoBlock *GetInfo(char *name, long access, BPTR *lock)
  80. {
  81.    struct FileInfoBlock *fib;
  82.  
  83.    *lock = Lock(name, access);
  84.    if (*lock == NULL)
  85.       return (NULL);
  86.  
  87.    fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock), 0);
  88.    if (fib == NULL) {
  89.       UnLock(*lock);
  90.       return (NULL);
  91.    }
  92.  
  93.    if (Examine(*lock, fib)) return (fib);
  94.    return (NULL);
  95. }
  96.  
  97. void FreeInfo(struct FileInfoBlock *fib, BPTR lock)
  98. {
  99.    FreeMem((char *)fib, sizeof(struct FileInfoBlock));
  100.    UnLock(lock);
  101. }
  102.  
  103. int check_size(char *name, long *bytes, long *blocks, long *files, int display)
  104.      
  105. {
  106.    struct FileInfoBlock *fib;
  107.    BPTR l;
  108.    int err = 0;
  109.    long byt = 0, blk = 0, fil = 0;
  110.  
  111.    fib = GetInfo(name, SHARED_LOCK, &l);
  112.    if (fib == NULL)
  113.       return (IoErr());
  114.  
  115.    if (fib->fib_DirEntryType > 0) /* Directory */
  116.    {
  117.       while (err == 0 && ExNext(l, fib)) /* Scan all files */
  118.       {
  119.          byt += fib->fib_Size;
  120.          blk += fib->fib_NumBlocks + 1;
  121.  
  122.          if (fib->fib_DirEntryType > 0) /* File is a directory */
  123.          {
  124.             int len = strlen(name) + strlen(fib->fib_FileName) + 2;
  125.             char *newname = AllocMem(len, 0);
  126.  
  127.             if (newname)
  128.             {
  129.                pathcat(strcpy(newname, name), fib->fib_FileName);
  130.                err = check_size(newname, &byt, &blk, &fil, subdisp);
  131.                FreeMem(newname, len);
  132.             }
  133.             else err = ERROR_NO_FREE_STORE;
  134.          }
  135.          else fil++;
  136.       }
  137.    }
  138.    else
  139.    {
  140.       byt = fib->fib_Size;
  141.       blk = fib->fib_NumBlocks + 1;
  142.       fil = 1;
  143.    }
  144.    if (err == 0) err = IoErr();
  145.  
  146.    FreeInfo(fib, l);
  147.  
  148.    if (err != ERROR_NO_MORE_ENTRIES) {
  149.       return (err);
  150.    }
  151.    if (display)
  152.    {
  153.       char *dirname = *name ? name : ".";
  154.  
  155.       if (verbose)
  156.          printf("%ls: %ld bytes, approximately %ld blocks in %ld files\n",
  157.                 dirname, byt, blk, fil);
  158.       else
  159.          printf("%ld\t%ls\n", blk, dirname);
  160.    }
  161.    *bytes += byt;
  162.    *blocks += blk;
  163.    *files += fil;
  164.  
  165.    return 0;
  166. }
  167.  
  168. /* du [-s] [-v] [names] */
  169. int analyse_opts(int argc, char **argv, int *nargc, char ***nargv)
  170. {
  171.    char *pname = *argv;
  172.  
  173.    argv++;
  174.    argc--;
  175.  
  176.    while (argc != 0 && **argv == '-')
  177.    {
  178.       if ((*argv)[2] == '\0')
  179.          switch ((*argv)[1])
  180.          {
  181.             case 's':
  182.                subdisp = FALSE;
  183.                break;
  184.             case 'v':
  185.                verbose = TRUE;
  186.                break;
  187.             default:
  188.                goto help;
  189.          }
  190.       else
  191.          goto help;
  192.  
  193.       argv++; argc--;
  194.    }
  195.    *nargc = argc; *nargv = argv;
  196.    return TRUE;
  197.  
  198. help:
  199.    printf("Usage: %ls [-s] [-v] [names]\n", pname);
  200.    return FALSE;
  201. }
  202.  
  203. void main(int argc, char *argv[])
  204. {
  205.    int err;
  206.    long bytes = 0, blocks = 0, files = 0;
  207.  
  208.    stdin = Input();
  209.    stdout = Output();
  210.  
  211.    if (analyse_opts(argc, argv, &argc, &argv))
  212.    {
  213.       if (argc == 0)
  214.          err = check_size("", &bytes, &blocks, &files, TRUE);
  215.       else
  216.          do
  217.          {
  218.             bytes = blocks = files = 0;
  219.             err = check_size(*argv, &bytes, &blocks, &files, TRUE);
  220.          }
  221.          while ((argv++, --argc) && err == 0);
  222.  
  223.       if (err) disp_error(err, "failed");
  224.    }
  225. }
  226.  
  227.